#pragma once

#ifdef WINDOWS
#include <winsock2.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#endif

namespace PC2
{

#ifdef WINDOWS
typedef SOCKET SOCKETTYPE;
#else
typedef int SOCKETTYPE;
#define SOCKET_ERROR -1
#endif

class Socket
{
public:
	enum TypeEnum
	{
		UDP
	};

public:
	int GetLastError();

public:
	Socket(TypeEnum aType = UDP);
	virtual ~Socket();

public:
	SOCKETTYPE GetNativeHandle();

public:
	int32_t Bind(char const* apAddr, unsigned short aPort, bool aReuse = true);

public:
	int32_t GetSocketError();

public:
	int32_t SetReceiveBufferSize(int aSize);

public:
	int32_t Connect(char const* apAddr, unsigned short aPort);
	int32_t Receive(char* apBuffer, int32_t aLength, int32_t aFlags);
	int32_t ReceiveFrom(char* apBuffer, int32_t aLength, int32_t aFlags, char* apSrcAddr, unsigned short* apSrcPort);
	int32_t Send(char const* apBuffer, int32_t aLength, int32_t aFlags);
	int32_t SendTo(char const* apAddr, unsigned short aPort, char const* apBuffer, int32_t aLength, int32_t aFlags);


public:
	int32_t SetNonBlockMode();

protected:
	SOCKETTYPE m_Socket;

};

}
